(module test-level1 mzscheme
  (require "../src/core.scm" "../src/prims/level0.scm" "../src/prims/level1.scm"
           "test-support.scm"
           (planet "test.ss" ("schematics" "schemeunit.plt" 2)))
  
  (provide level-1-tests)
  
  ;; All the unit tests available online for the level 0 primitives
  (define level-1-tests
    (test-suite "Level 1 Unit Tests"
                (test-suite "Basic Combinators"
                            (cat-unit-test "apply" [1] apply 1 eq)
                            (cat-unit-test "apply2" 1 3 [inc] apply2 pop 2 eq)
                            (cat-unit-test "dip" 1 3 [inc] dip pop 2 eq)
                            (cat-unit-test "dip2" 1 3 5 [inc] dip2 pop pop 2 eq))
                (test-suite "Classical Combinators")
                (test-suite "Boolean Operations"
                            (cat-unit-test "and" true true and)
                            (cat-unit-test "nand" true false nand)
                            (cat-unit-test "nor" false false nor)
                            (cat-unit-test "not" false not)
                            (cat-unit-test "or" true false or))
                (test-suite "Comparison Functions"
                            (cat-unit-test "eqz" 0 eqz popd)
                            (cat-unit-test "eqf" 3 3 eqf apply popd)
                            (cat-unit-test "neq" 3 5 neq)
                            (cat-unit-test "neqf" 3 5 neqf apply popd)
                            (cat-unit-test "neqz" 3 neqz popd))
                (test-suite "Function Construction"
                            (cat-unit-test "curry" 1 2 [add_int] curry apply 3 eq)
                            (cat-unit-test "curry2" 1 2 [add_int] curry2 apply 3 eq)
                            (cat-unit-test "rcompose" 1 [add_int] [2] rcompose apply 3 eq)
                            (cat-unit-test "rcurry" 1 [add_int] 2 rcurry apply 3 eq))
                (test-suite "Looping Functions"
                            (cat-unit-test "for" nil [cons] 3 for 0 1 2 triple eq)
                            (cat-unit-test "for_each" 8 1 2 pair [add_int] for_each 11 eq)
                            (cat-unit-test "repeat" 1 [inc] 5 repeat 6 eq)
                            (cat-unit-test "rfor" nil [cons] 3 rfor 3 2 1 triple eq)
                            (cat-unit-test "whilen" 1 [inc] [dup 3 gt_int] whilen 4 eq)
                            (cat-unit-test "whilene" 0 1 2 3 triple [uncons swap [add_int] dip] whilene 6 eq)
                            (cat-unit-test "whilenz" 3 3 [[inc] dip dec] whilenz 6 eq))
                (test-suite "List Functions"
                            (cat-unit-test "cat" 1 unit 2 unit cat nil 1 cons 2 cons eq)
                            (cat-unit-test "consd" nil 1 2 consd pop head 1 eq)
                            (cat-unit-test "count" 1 2 pair count popd 2 eq)
                            (cat-unit-test "count_while" 1 2 3 triple [1 gt_int] count_while popd 2 eq)
                            (cat-unit-test "drop" 3 4 pair 1 drop head 3 eq)
                            (cat-unit-test "drop_while" 1 2 3 triple [2 gteq_int] drop_while 1 unit eq)
                            (cat-unit-test "filter" 1 2 3 triple [2 mod_int 0 eq] filter 2 unit eq)
                            (cat-unit-test "first" 1 2 pair first popd 2 eq)
                            (cat-unit-test "flatten" nil 1 unit cons 2 unit cons flatten 1 2 pair eq)
                            (cat-unit-test "fold" 1 2 3 triple 0 [add_int] fold 6 eq)
                            (cat-unit-test "gen" 0 [inc] [2 lt_int] gen 0 1 pair eq)
                            (cat-unit-test "head" nil 1 cons 2 cons head 2 eq)
                            (cat-unit-test "last" 1 2 3 triple last popd 1 eq)
                            (cat-unit-test "map" 1 2 pair [3 mul_int] map head 6 eq)
                            (cat-unit-test "mid" 1 2 3 triple mid popd 2 eq)
                            (cat-unit-test "move_head" 1 2 pair 3 4 pair move_head pop head 4 eq)
                            (cat-unit-test "n" 3 n 0 1 2 triple eq)
                            (cat-unit-test "nth" 1 2 3 triple 2 nth popd 1 eq)
                            (cat-unit-test "pair" 1 2 pair head 2 eq)
                            (cat-unit-test "rev" 1 2 pair rev head 1 eq)
                            (cat-unit-test "rmap" 1 2 pair [3 mul_int] rmap head 3 eq)
                            (cat-unit-test "set_at" 1 2 pair 42 0 set_at head 42 eq)
                            (cat-unit-test "small" 1 unit small popd)
                            (cat-unit-test "split" 1 2 3 triple [2 mod_int 0 eq] split popd 1 3 pair eq)
                            (cat-unit-test "split_at" 1 2 3 triple 1 split_at pop 1 2 pair eq)
                            (cat-unit-test "swons" 1 2 unit swons 2 1 pair eq)
                            (cat-unit-test "tail" 3 4 pair tail 3 unit eq)
                            (cat-unit-test "take" 1 2 3 triple 2 take 2 3 pair eq)
                            (cat-unit-test "take_while" 1 2 3 triple [2 gt_int] take_while 3 unit eq)
                            (cat-unit-test "triple" 1 2 3 triple 1 2 pair 3 cons eq)
                            (cat-unit-test "unpair" 1 2 pair unpair pop 1 eq)
                            (cat-unit-test "unit" 1 unit nil 1 cons eq))
                (test-suite "Stack Manipulation" 
                            (cat-unit-test "bury" 1 2 3 bury pop pop 3 eq)
                            (cat-unit-test "dig" 1 2 3 dig popd popd 1 eq)
                            (cat-unit-test "dup2" 1 2 dup2 pop popd popd 1 eq)
                            (cat-unit-test "dupd" 1 2 dupd pop popd 1 eq)
                            (cat-unit-test "over" 1 2 over popd popd 1 eq)
                            (cat-unit-test "peek" 1 2 3 peek popd popd popd 1 eq)
                            (cat-unit-test "poke" 1 2 3 poke pop 3 eq)
                            (cat-unit-test "pop2" 1 2 3 pop2 1 eq)
                            (cat-unit-test "pop3" 1 2 3 4 pop3 1 eq)
                            (cat-unit-test "popd" 1 2 popd 2 eq)
                            (cat-unit-test "swap2" 1 2 3 4 swap2 pop3 3 eq)
                            (cat-unit-test "swapd" 1 2 3 swapd pop2 2 eq)
                            (cat-unit-test "under" 1 2 under pop2 2 eq))
                (test-suite "Integer Operations"
                            (cat-unit-test "dec" 3 dec 2 eq)
                            (cat-unit-test "even" 2 even popd)
                            (cat-unit-test "inc" 3 inc 4 eq)
                            (cat-unit-test "sub_int" 5 3 sub_int 2 eq)
                            (cat-unit-test "min_int" 3 5 min_int 3 eq)
                            (cat-unit-test "max_int" 3 5 max_int 5 eq)
                            (cat-unit-test "od" 3 odd popd)
                            (cat-unit-test "gt_int" 5 3 gt_int)
                            (cat-unit-test "gteq_int" 5 5 gteq_int)
                            (cat-unit-test "lteq_int" 3 5 lteq_int)))))
